查看原文
其他

互联网安全知多少

曲健Nicholas 曲水流觞TechRill 2020-02-06

关注曲水流觞TechRill

交流学习一起HIGH !

secu

R

ity

W·E·B·安·全



当今互联网行业,特别是初创公司雨后春笋般,大部分公司对安全的重视、投入或者理解都是不足的。


如此导致,没有事故其乐融融,一旦出事慌慌张张。亡羊补牢不是我们的出路,未雨绸缪,防患未然才是。


最近把道哥的《白帽子讲Web安全》重新翻了翻,挑出一些比较容易被忽视的点给大家也给自己刷新一下#安全#观念。


黑名单是非常不好的设计思想


设计安全方案

-白帽子兵法


 1 

Secure By Default 原则

设计安全方案的基本原则,中文翻译“默认安全”不太好理解,其实就包含两层含义:白名单/黑名单思想,和最小权限原则。


两者从字面就比较好理解,这里必须特别强调一下“尽量更多的使用白名单,少用黑名单”,这样可以保证安全的范围可控,权限最小。


比如制定Web服务器的防火墙策略,正确做法是只开放80和443端口,屏蔽除此之外的其他端口,这就是“白名单”做法。而如果使用“黑名单”,假设不允许SSH端口对公网开放,那策略可能只把默认的22端口放入了黑名单中,万事大吉了么?实际情况是,工程师为了偷懒或者图方便,私自把SSH的监听端口改成了2222,绕过了黑名单策略。懵逼了吧?


 2 

纵深防御原则

Defense in Depth 也是设计安全方案的重要指导思想。就像你不光在HMTL表单上有JS的字段校验,服务端也有校验,达到层层过滤的效果。因为在一个环节设置所有的防御措施是不可能的,把风险分散到各个层面进行拦截也不失为一种稳妥的办法。


 3 

数据与代码分离原则

大多数“注入”引发的安全问题都是违背了这个原则,比如“SQL注入”就是把不合法的用户输入拼接起来进行了非法的数据库操作。其他类似XSS, CRLF注入亦同。


 4 

不可预测原则

该原则与前面三种不同,更多的是从克服攻击方法的角度看问题。它就妙在即使无法修复code来保证安全,我也能够使攻击的方法无效,或者只是提高攻击的门槛,都可以算做成功的防御。


比如论坛的帖子序号假设是升序自增长的,那么攻击者想要批量删除文章,脚本只要简单的递增循环就搞定了。但如果按照“不可预测”原则,帖子的序号是随机的类似uuid的不可预测值,那必然提高了攻击者遍历所有帖子序号的门槛。


强调字符编码的一致性真的不仅仅是为了

看起来/运行起来不乱码而已

Character Encoding Consistency


编码问题


现而今互联网应用普遍会要求研发环境所有字符编码必须是UTF-8(还在用GBK?那是铁了心不想进军国际)。统一编码对很多人可能只是意味着:打开IDE不乱码,前后端数据传输不乱码等等。其实混乱的字母编码很可能导致安全问题!


在GBK字符集中,0xbf27 不是一个有效的多字节字符,在解析为单字节字符的过程中, 0xbf27 变成了 0xbf(¿)0x27(') 双字符0xbf5c 是GBK字符集里有效的中文字符()。

该漏洞早在2006年就被发现,国外用来讨论数据库字符集设为GBK时,在进入数据库之前,比如PHP中使用addslashes()函数,或者开启magic_quotes_gpc时,添加的转义符就会造成的这个注入漏洞。

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string 

假设一张users表,查询语句是

select * from users 

where username = '$input_username'

and password = '$input_password'


攻击者输入的密码是:

0xbf27 or '1'='1


因为 0xbf27 不是有效字符,经过PHP addslashes() 转义后会在 bf 和 27 之间添加转义符 ("\"的ASCII 码为 0x5c), 最终变成了0xbf5c27


而 0xbf5c 正好对应GBK字符(),所以SQL到数据库里就变成了

select * from users 

where username = '$input_username'

and password = '縗' or '1'='1'


SQL列截断攻击

在设计可变长度列的时候,到底设置多长很多人是拍脑袋,就算突然哪天发现长度不够了,大不了 Alter 加长一下呗。 但是实际情况是,这里就有漏洞!


MYSQL 里面有个 sql_mode 选项,设置为default时,意味着没有开启 STRICT_ALL_TABLES选项,用户插入超长的值只会提示warning, 而不是 error 报异常。利用这点就可以实现越权访问等攻击。


WordPress就出现过一个真实的案例,注册一个用户名为“admin (55个空格) x”的用户,存到数据库的时候被截断了,这样数据库里就有两用户名是 admin 的记录。当然你可以说第二条有空格不会用等式查询没问题,但如果出现 like 之类的语句呢,谁也不敢保证。


CRLF注入

CR回车 (ASCII 13, \r, 0x0d), 本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return。

LF = 换行 (ASCII 10, \n, 0x0a), 本义是光标往下一行(不一定到下一行行首),n的英文newline,控制字符可以写成LF,即Line Feed

在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。


于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。


白帽子中讲的第一个场景是日志文件注入,通过换行符可以打印一些伪造的日志,但是实用性比较弱。另一个危害比较大,是“注入HTTP头”。


在HTTP协议中,HTTP头是通过“\r\n”来分割的,这种CRLF注入也叫“Http Response Splitting”,字面就说明白了,就是把应答的 body 给肢解了,攻击者把自己的代码注入到肢解后的原本页面代码中,达到攻击目的。



加密算法攻击

常见的对称加密算法分为分组加密算法流密码加密算法两种。


分组加密算法基于“分组”(block)进行操作,根据算法的不同,每个分组的长度可能不同。代表算法有DES, 3-DES, Blowfish, IDEA, AES等。


而流密码加密算法,则每次只处理一个字节,加密和解密双方使用相同伪随机加密数据流,一般都是逐位异或随机密码本的内容。代表有 RC4, ORYX, SEAL 等。


 1 

流密码攻击


流密码加密算法的性能非常好,因此非常受开发者的环境。但是在流密码的使用中,最常见的错误便是使用同一个秘钥进行多次加解密。破解流密码的这种攻击称作 “Reused Key Attack”,在这种攻击下,攻击者不需要知道秘钥就可以还原出明文。


基本原理通过简单的公式推导就可以理解。假设明文A,和明文B,秘钥C,那么 XOR 异或加密可表示为:

E(A) = A xor C

E(B) = B xor C

我们知道密文肯定是公之于众的,又知道相同的两个数字进行 XOR 异或运算结果为 0,由此可得:

E(A) xor E(B) = (A xor C) xor (B xor C) = A xor B xor C xor C = A xor B

即:

E(A) xor E(B) = A xor B

这个公式四个数值,意味着只需要知道其中三个,就可以推导出剩下的一个。而公式中完全没有秘钥C的存在...


攻击原理也就清晰了,我先通过合法请求获取到明文 A 对应的密文 E(A),然后拿到另一个用户的密文 E(B), 可以轻松反推出明文 B 来。


有关流密码的攻击方法还有几种,诸如 Bit-flipping Attack, 弱随机 IV 问题,WEP破解等等。总之,这一切都提醒我们,作为开发者在使用任何一个加密算法的时候,一定要将其原理研究透彻,否则自认为的"安全"都可能沦为别人的笑柄。


 2 

ECB模式的缺陷

分组加密算法,除了算法本身,还有一些通用的加密模式,常见的有:ECB, CBC, CFB, OFB, CTR 等。如果加密模式被攻击,那么不论加密算法的秘钥有多长, 都可能不安全。


ECB模式(电码簿模式)是最简单的一种加密模式,它的每个分组之间相对独立,加密过程如图:

ECB模式最大的问题也就除非分组的独立性上:攻击者只需对调任意分组的密文,在经过解密后,所得的明文顺序也是经过对调的。


来个直观的例子,很容易理解。假设某个支付应用中,用户提交的密文对应的明文是:

member=abc||pay=10000.00

其中前16个字节为:

member=abc||pay=

这正好是一个或者两个分组的长度,因此攻击者只需要使用“1.00”的密文,替换“10000.00”的密文,就可以伪造支付金额从10000元变成了1元。


注意,ECB模式的缺陷并非是某个加密算法的问题,即使强壮如 AES-256 算法,只要使用ECB模式,也无法避免这问题。因此,当需要加密的明文长度大于一个分组的长度是,应当避免使用ECB模式。


有些同学会说,以后就用 CBC分组链式加密模式,肯定没问题了。少年,天下没有无缝的蛋。其实针对CBC模式的“Padding Oracle Attack” 在2002年就出现了,但是 CBC 确实比 ECB的攻击难度要大很多,有兴趣的同学可以研究下。



结语


互联网安全是个很大的话题,白帽子一书中将其划分成四大部分:世界观安全、客户端脚本安全、服务器端应用安全、公司安全运营(业务安全),身为互联网人,

安全防范, 责无旁贷


IOS 专用打赏码


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存